﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using OpenComposite.Controls;
using OpenComposite.Repository.TFS;

namespace OpenComposite.EII.Designer.Workflow.Forms
{
	public partial class FormWorkflowOptions : Form
	{
		#region Initialization
		public FormWorkflowOptions(Repository.Workflow workflow)
			: this(workflow, false)
		{
		}
		public FormWorkflowOptions(Repository.Workflow workflow, bool hideCorrelation)
		{
			_workflow = workflow;
			_currentToken = null;

			InitializeComponent();

			#region Init Inner Tab Control Controls (SqlConnectionControl)

			sqlConnPersistence = new SqlConnectionControl();
			tabPersistenceSQL.Controls.Add(sqlConnPersistence);
			//sqlConnPersistence.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
			sqlConnPersistence.Dock = DockStyle.Top;
			sqlConnPersistence.Width = tabPersistenceSQL.ClientSize.Width - 10;
			sqlConnPersistence.Location = new Point(2, 2);
			lnkCopyFromTracking.Location = new Point(
				sqlConnPersistence.Location.X + sqlConnPersistence.Width - lnkCopyFromTracking.Width - 90,
				sqlConnPersistence.Location.Y);
			sqlConnTracking = new SqlConnectionControl();
			tabTrackingSQL.Controls.Add(sqlConnTracking);
			//sqlConnTracking.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
			sqlConnTracking.Dock = DockStyle.Top;
			sqlConnTracking.Width = tabTrackingSQL.ClientSize.Width - 10;
			sqlConnTracking.Location = new Point(2, 2);
			sqlConnTracking.BringToFront();
			lnkCopyFromPersistence.Location = new Point(
				sqlConnTracking.Location.X + sqlConnTracking.Width - lnkCopyFromPersistence.Width - 90,
				sqlConnTracking.Location.Y);

			#endregion

			if ( hideCorrelation ) {
				tabCtrlOptions.TabPages.Remove(tabInstCorrelations);
			}

			if ( !Global.Status.HasSourceControl ) {
				gbxSourceControl.Visible = false;
			}

			this.DialogResult = DialogResult.Cancel;
		}
		#endregion

		private SqlConnectionControl sqlConnPersistence = null;
		private SqlConnectionControl sqlConnTracking = null;

		#region Public Members

		#region Properties
		#endregion

		#region Methods
		#endregion

		#endregion

		#region Private Members

		#region Fields
		private Repository.Workflow _workflow;
		private string _currentToken;
		#endregion

		#region Methods
		#endregion

		#region Event Handlers
		private void FormGenerateOptions_Load(object sender, EventArgs e)
		{
			this.Text += " - " + _workflow.Name;
			cmbWFInstCorrelation.SelectedIndex = (int)_workflow.ExtendedProperties.CorrelationType;
			dgvCorrTokens.AutoGenerateColumns = false;
			dgvCorrTokens.Rows.Clear();
			foreach ( var item in _workflow.ExtendedProperties.CorrelationParameters ) {
				dgvCorrTokens.Rows.Add(item);
			}
			dgvEvents.AutoGenerateColumns = false;
			dgvEvents.DataSource = _workflow.Interface.Events;
			dgvMethods.AutoGenerateColumns = false;
			dgvMethods.DataSource = _workflow.Interface.Methods;

			cbxUseBasicHttpBinding.Checked = _workflow.ExtendedProperties.UseBasicHttpBinding;

			cbxDefaultPersistence.Checked = _workflow.ExtendedProperties.UseDefaultPersistence;
			cbxDefaultTracking.Checked = _workflow.ExtendedProperties.UseDefaultTracking;
			sqlConnPersistence.ConnectionString = _workflow.ExtendedProperties.DefaultPersistenceConnection;
			sqlConnTracking.ConnectionString = _workflow.ExtendedProperties.DefaultTrackingConnection;
			cbxUseTransactionForTracking.Checked = _workflow.ExtendedProperties.IsTransactional;

			if ( _workflow.ExtendedProperties.ConfigurationLevel == OpenComposite.EII.Repository.ConfigurationLevel.CompleteCodeGeneration ) {
				rbnCompleteCodeGen.Checked = true;
			} else if ( _workflow.ExtendedProperties.ConfigurationLevel == OpenComposite.EII.Repository.ConfigurationLevel.UtilizeConfiguration ) {
				rbnUtilizeConfiguration.Checked = true;
			}

			txtSourceControlPath.Text = _workflow.ExtendedProperties.SourceControlPath;
			cbxConnectWithSourceControl.Checked = _workflow.ExtendedProperties.ConnectWithSourceControlOnDeploy;
		}
		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			setCorrParams();
			_workflow.ExtendedProperties.CorrelationType = (OpenComposite.EII.Repository.InstanceCorrelationType)cmbWFInstCorrelation.SelectedIndex;

			_workflow.ExtendedProperties.UseBasicHttpBinding = cbxUseBasicHttpBinding.Checked;

			_workflow.ExtendedProperties.UseDefaultPersistence = cbxDefaultPersistence.Checked;
			_workflow.ExtendedProperties.UseDefaultTracking = cbxDefaultTracking.Checked;
			_workflow.ExtendedProperties.DefaultPersistenceConnection = sqlConnPersistence.ConnectionString;
			_workflow.ExtendedProperties.DefaultTrackingConnection = sqlConnTracking.ConnectionString;
			_workflow.ExtendedProperties.IsTransactional = cbxUseTransactionForTracking.Checked;

			if ( rbnUtilizeConfiguration.Checked ) {
				_workflow.ExtendedProperties.ConfigurationLevel = OpenComposite.EII.Repository.ConfigurationLevel.UtilizeConfiguration;
			} else if ( rbnCompleteCodeGen.Checked ) {
				_workflow.ExtendedProperties.ConfigurationLevel = OpenComposite.EII.Repository.ConfigurationLevel.CompleteCodeGeneration;
			}

			_workflow.ExtendedProperties.ConnectWithSourceControlOnDeploy = cbxConnectWithSourceControl.Checked;
			_workflow.ExtendedProperties.SourceControlPath = txtSourceControlPath.Text;

			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		private void setCorrParams()
		{
			_workflow.ExtendedProperties.CorrelationParameters.Clear();
			foreach ( DataGridViewRow item in dgvCorrTokens.Rows ) {
				if ( item.IsNewRow ) continue;
				string s = item.Cells[0].Value as string;
				if ( !string.IsNullOrEmpty(s) ) {
					_workflow.ExtendedProperties.CorrelationParameters.Add(s);
				}
			}
		}
		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.Cancel;
			this.Close();
		}

		private void cmbWFInstCorrelation_SelectedIndexChanged(object sender, EventArgs e)
		{
			if ( cmbWFInstCorrelation.SelectedIndex == 2 ) {
				grpDocCorr.Visible = true;
			} else {
				grpDocCorr.Visible = false;
			}
		}

		private void dgvMethods_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.RowIndex >= 0 && e.ColumnIndex == colMethodEditAlias.Index ) {
				setCorrParams();
				FormEditAliases frm = new FormEditAliases(
					dgvMethods.Rows[e.RowIndex].DataBoundItem as Repository.WorkflowMethod);
				frm.ShowDialog();
				dgvMethods.UpdateCellValue(colMethodAlias.Index, e.RowIndex);
			}
		}

		private void dgvEvents_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.RowIndex >= 0 && e.ColumnIndex == colEventEditAlias.Index ) {
				setCorrParams();
				FormEditAliases frm = new FormEditAliases(
					dgvEvents.Rows[e.RowIndex].DataBoundItem as Repository.WorkflowEvent);
				frm.ShowDialog();
				dgvEvents.UpdateCellValue(colEventAlias.Index, e.RowIndex);
			}
		}

		private void dgvCorrTokens_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
		{
		}
		private void dgvCorrTokens_CellValueChanged(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.RowIndex < 0 || e.RowIndex >= dgvCorrTokens.Rows.Count ||
				 e.ColumnIndex != colCorrTokenName.Index ) {
				return;
			}
			string newValue = dgvCorrTokens[e.ColumnIndex, e.RowIndex].Value as string;
			if ( newValue != _currentToken ) {
				foreach ( var method in _workflow.Interface.Methods ) {
					foreach ( var alias in method.ExtendedProperties.CorrelationAliases ) {
						if ( alias.ParameterName == _currentToken ) {
							alias.ParameterName = newValue;
						}
					}
				}
				foreach ( var wfevent in _workflow.Interface.Events ) {
					foreach ( var alias in wfevent.ExtendedProperties.CorrelationAliases ) {
						if ( alias.ParameterName == _currentToken ) {
							alias.ParameterName = newValue;
						}
					}
				}
			}
			dgvMethods.Refresh();
			dgvEvents.Refresh();
		}
		private void dgvCorrTokens_CurrentCellChanged(object sender, EventArgs e)
		{
			if ( dgvCorrTokens.CurrentRow == null ) {
				_currentToken = null;
			} else {
				_currentToken = dgvCorrTokens.CurrentRow.Cells[0].Value as string;
			}
		}
		private void dgvCorrTokens_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
		{
			string deleting = e.Row.Cells[0].Value as string;
			List<Repository.CorrelationAlias> lstRemove = new List<OpenComposite.EII.Repository.CorrelationAlias>();
			foreach ( var method in _workflow.Interface.Methods ) {
				lstRemove.Clear();
				foreach ( var alias in method.ExtendedProperties.CorrelationAliases ) {
					if ( alias.ParameterName == deleting ) {
						lstRemove.Add(alias);
					}
				}
				foreach ( var item in lstRemove ) {
					method.ExtendedProperties.CorrelationAliases.Remove(item);
				}
			}
			foreach ( var wfevent in _workflow.Interface.Events ) {
				lstRemove.Clear();
				foreach ( var alias in wfevent.ExtendedProperties.CorrelationAliases ) {
					if ( alias.ParameterName == deleting ) {
						lstRemove.Add(alias);
					}
				}
				foreach ( var item in lstRemove ) {
					wfevent.ExtendedProperties.CorrelationAliases.Remove(item);
				}
			}
			dgvMethods.Refresh();
			dgvEvents.Refresh();
		}

		private void btnCopyFromPersistence_Click(object sender, EventArgs e)
		{
		}

		private void btnCopyFromTracking_Click(object sender, EventArgs e)
		{
		}


		#endregion

		private void cbxDefaultPersistence_CheckedChanged(object sender, EventArgs e)
		{
			showSqlConnectionTabs();
		}

		private void cbxDefaultTracking_CheckedChanged(object sender, EventArgs e)
		{
			showSqlConnectionTabs();
		}

		private void showSqlConnectionTabs()
		{
			if ( !cbxDefaultPersistence.Checked && !cbxDefaultTracking.Checked ) {
				tabControl1.Visible = false;
			} else {
				tabControl1.Visible = true;
				lnkCopyFromTracking.Visible = cbxDefaultTracking.Checked;
				lnkCopyFromPersistence.Visible = cbxDefaultPersistence.Checked;
				if ( cbxDefaultTracking.Checked ) {
					if ( !tabControl1.TabPages.Contains(tabTrackingSQL) ) {
						tabControl1.TabPages.Add(tabTrackingSQL);
					}
				} else {
					if ( tabControl1.TabPages.Contains(tabTrackingSQL) ) {
						tabControl1.TabPages.Remove(tabTrackingSQL);
					}
				}
				if ( cbxDefaultPersistence.Checked ) {
					if ( !tabControl1.TabPages.Contains(tabPersistenceSQL) ) {
						tabControl1.TabPages.Add(tabPersistenceSQL);
					}
				} else {
					if ( tabControl1.TabPages.Contains(tabPersistenceSQL) ) {
						tabControl1.TabPages.Remove(tabPersistenceSQL);
					}
				}
			}
		}

		#endregion

		private void lnkCopyFromPersistence_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			if ( sqlConnPersistence.IsEmpty ) {
				if ( MessageBox.Show("The Persistence Connection is empty. Do you want to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
						== DialogResult.No ) {
					return;
				}
			}
			sqlConnTracking.ConnectionString = sqlConnPersistence.ConnectionString;
		}

		private void lnkCopy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			if ( sqlConnTracking.IsEmpty ) {
				if ( MessageBox.Show("The Tracking Connection is empty. Do you want to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
						== DialogResult.No ) {
					return;
				}
			}
			sqlConnPersistence.ConnectionString = sqlConnTracking.ConnectionString;
		}

		private void btnSelectSourceControl_Click(object sender, EventArgs e)
		{
			if ( !cbxConnectWithSourceControl.Checked ) {
				MessageBox.Show(string.Format("\"{0}\" must be checked.", cbxConnectWithSourceControl.Text), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			string servername = _workflow.ExtendedProperties.SourceControlServer;
			string workspacename = _workflow.ExtendedProperties.SourceControlTfsWorkspace;
			string path = txtSourceControlPath.Text;

			if ( TeamFoundationWrapper.SelectSourceControl(
					ref servername, ref workspacename, ref path) ) {
				// if new source selected then set server settings
				_workflow.ExtendedProperties.SourceControlServer = servername;
				_workflow.ExtendedProperties.SourceControlTfsWorkspace = workspacename;
				txtSourceControlPath.Text = path;
			}
		}

		private void cbxConnectWithSourceControl_CheckedChanged(object sender, EventArgs e)
		{
			txtSourceControlPath.Enabled = cbxConnectWithSourceControl.Checked;
			btnSelectSourceControl.Enabled = cbxConnectWithSourceControl.Checked;
		}

		private void linkIsTransactionalHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			//string message = string.Format("Activating this option will force tracking to go with workflow transactions.{0}{0}In most cases this will hold the SQL Tracking Service from writing tracked data to the database until the process has ended.", Environment.NewLine);
			string message = string.Format("If activated, this option will keep the SQL Tracking Service from writing to the database until the end of a transaction (like SQL Persistence).{0}In most cases this is at the end of the process.", Environment.NewLine);
			MessageBox.Show(message, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
	}
}
